package cn.gz.demo.ui;

import android.os.Bundle;
import android.os.Handler;
import android.view.View;

import androidx.databinding.DataBindingUtil;

import java.util.concurrent.TimeUnit;

import cn.gz.demo.R;
import cn.gz.demo.databinding.WebSocketBinding;
import cn.gz.demo.ui.base.BaseActivity;
import cn.gz.demo.utils.LogUtil;
import cn.gz.demo.utils.SystemUtil;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

/**
 * @author Liuyz
 * @date 2020/6/811:33
 * https://www.jianshu.com/p/e095f5cafc7e
 */
public class WebSocketActivity extends BaseActivity {
    private WebSocketBinding binding;
    private WebSocket mSocket;
    private boolean isConnect = false;
    private long sendTime = 0L;
    // 发送心跳包
    private Handler mHandler;
    // 每隔2秒发送一次心跳包，检测连接没有断开
    private static final long HEART_BEAT_RATE = 5 * 1000;
    int number = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_websocket);

        initView();
        binding.send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ++number;
                mSocket.send("连接成功！...." + number);
            }
        });
        binding.receive.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                closeLink();
            }
        });
        binding.relink.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                closeLink();
                closeHart();
                initView();
            }
        });
    }

    OkHttpClient mOkHttpClient;
    Request request;
    EchoWebSocketListener socketListener;

    private void initView() {
        mOkHttpClient = new OkHttpClient.Builder()
                .readTimeout(3, TimeUnit.SECONDS)//设置读取超时时间
                .writeTimeout(3, TimeUnit.SECONDS)//设置写的超时时间
                .connectTimeout(3, TimeUnit.SECONDS)//设置连接超时时间
                .build();

        request = new Request.Builder().url("ws://10.10.1.55/immgr/websocket/app/online/" + SystemUtil.getIMEI(context) + "/10000").build();
        socketListener = new EchoWebSocketListener();

        // 刚进入界面，就开启心跳检测
        mHandler = new Handler();
        mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);

        mOkHttpClient.newWebSocket(request, socketListener);
        mOkHttpClient.dispatcher().executorService().shutdown();

    }

    // 发送心跳包
    private Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
            if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
                boolean link = isConnect();
                LogUtil.showLog(".......link....." + link);
                if (!link) {
                    closeLink();
                    closeHart();
                    initView();
                }
                sendTime = System.currentTimeMillis();
            }
            mHandler.postDelayed(this, HEART_BEAT_RATE); //每隔一定的时间，对长连接进行一次心跳检测
        }
    };

    private final class EchoWebSocketListener extends WebSocketListener {

        //连接成功
        @Override
        public void onOpen(WebSocket webSocket, Response response) {
            super.onOpen(webSocket, response);
            mSocket = webSocket;
            mSocket.send("连接成功!");
            isConnect = true;
        }

        // 接收消息
        @Override
        public void onMessage(WebSocket webSocket, ByteString bytes) {
            super.onMessage(webSocket, bytes);
        }

        // 接收消息
        @Override
        public void onMessage(WebSocket webSocket, String text) {
            super.onMessage(webSocket, text);
        }

        // 断开
        @Override
        public void onClosed(WebSocket webSocket, int code, String reason) {
            super.onClosed(webSocket, code, reason);
            LogUtil.showLog("断开链接");
            isConnect = false;
            closeLink();
        }

        // 断开中
        @Override
        public void onClosing(WebSocket webSocket, int code, String reason) {
            super.onClosing(webSocket, code, reason);
        }

        // 失败
        @Override
        public void onFailure(WebSocket webSocket, Throwable t, Response response) {
            super.onFailure(webSocket, t, response);
        }
    }

    /**
     * 是否连接
     */
    public boolean isConnect() {
        return mSocket != null && isConnect;
    }

    /**
     * 关闭连接
     */
    public void closeLink() {
        if (mSocket != null) {
            mSocket.close(1000, null);
            mSocket = null;
        }
    }

    /**
     * 关闭心跳检测
     */
    public void closeHart() {
        if (mHandler != null) {
            mHandler.removeCallbacksAndMessages(null);
            mHandler = null;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        closeLink();
        closeHart();
    }
}
